package org.wwb.antbox.user.service.user;

import org.ant.commons.commons.security.AuthTool;
import org.ant.commons.models.model.BaseIdModel;
import org.ant.commons.models.result.BaseResult;
import org.ant.service.common.BaseService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wwb.antbox.user.data.passport.PassportMapper;
import org.wwb.antbox.user.iservice.passport.IPassportService;
import org.wwb.antbox.user.model.common.exception.AccountDisabledException;
import org.wwb.antbox.user.model.common.exception.AccountInActiveException;
import org.wwb.antbox.user.model.common.exception.AccountPasswordException;
import org.wwb.antbox.user.model.passport.model.PwdEditModel;
import org.wwb.antbox.user.model.passport.view.RoleNamesAndPermissionsView;
import org.wwb.antbox.user.model.rolemenu.view.RoleMenuListView;
import org.wwb.antbox.user.model.user.entity.SysUser;
import org.wwb.antbox.user.model.user.enums.SysUserStatusEnum;
import org.wwb.antbox.user.model.user.model.SysUserFreezeModel;
import org.wwb.antbox.user.model.user.model.SysUserLoginModel;
import org.wwb.antbox.user.model.user.model.SysUserOnlineTimeModel;
import org.wwb.antbox.user.model.userrole.view.UserRoleListView;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.login.LoginException;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Author Bond
 * @Date: 19-9-5 15:48
 * @Description: 用户登录相关服务接口实现
 */
@Service(registry = {"registryConfigUser"},provider ="dubboProviderUser")
public class PassPortServiceImpl extends BaseService<PassportMapper, SysUser, String> implements IPassportService {

    @Override
    public BaseResult<SysUser> checkLoginSysUser(SysUserLoginModel sysUserLoginModel) throws LoginException {
        SysUser sysUser = mapper.getByQuery(sysUserLoginModel.queryByLoginName());

        // 根据用户名查询是否存在该用户
        if(null == sysUser){
            String message = MessageFormat.format("登录账号:【{0}】不存在!",sysUserLoginModel.getLoginName());
            throw new AccountNotFoundException(message);
        }

        // 加密后的密码
        String password = AuthTool.md5SysUserPassword(sysUserLoginModel.getLoginPwd(), sysUserLoginModel.getLoginName());

        // 比较密码是否相同
        if(!password.equals(sysUser.getLoginPwd())){
            String message = MessageFormat.format("登录账号:【{0}】密码不对!",sysUserLoginModel.getLoginName());
            throw new AccountPasswordException(message,sysUser.getId());
        }

        // 判断用户状态是否被停用
        if(SysUserStatusEnum.DISABLED.getCode().equals(sysUser.getStatus())){
            String message = MessageFormat.format("登录账号:【{0}】被停用!",sysUserLoginModel.getLoginName());
            throw new AccountDisabledException(message);
        }

        // 判断用户状态是否被冻结
        if(SysUserStatusEnum.LOCKED.getCode().equals(sysUser.getStatus())){
            String message = MessageFormat.format("登录账号:【{0}】被冻结!",sysUserLoginModel.getLoginName());
            throw new AccountInActiveException(message);
        }

        BaseResult<SysUser> baseResult = new BaseResult<>();
        baseResult.setSuccess(true);
        baseResult.setModel(sysUser);
        return baseResult;
    }

    @Override
    public BaseResult<RoleNamesAndPermissionsView> getUserRoleNamesAndPermissions(BaseIdModel<String> userIdModel) {
        Set<String> userRoleNames = new HashSet<>();
        Set<String> allPermissions = new HashSet<>();

        /**
         * 获取系统用户拥有的角色菜单关系集合
         *
         * 用户拥有的--->用户角色关系集合--->角色菜单关系集合
         *
         * 一、获取系统用户拥有的角色菜单关系集合
         * 1、系统用户和角色关系，如果用户和角色关系集合为空，则表示用户没有角色，没有角色就不用进行了，角色菜单关系肯定为空
         * 2、如果系统用户和角色关系返回的视图不为空，则代表该用户拥有1个或多个角色
         * 3、再根据角色id集合 去角色菜单关系表中获取角色对应的所有角色功能菜单关系集合
         *
         *
         * 二、获取用户权限集合
         *
         * 用户拥有总菜单集合 = 用户角色对应的菜单集合 + 用户对应的菜单集合
         *
         * 1、用户拥有的--->用户菜单关系集合     根据用户id去用户菜单关系表中查询出，用户拥有的菜单集合
         * 2、再根据所有的菜单集合id获取功能菜单信息
         *
         */

        /**
         * 获取用户角色关系集合
         */
        List<UserRoleListView> userRoleList = mapper.getSysUserRoleList(userIdModel.getId());
        for (UserRoleListView userRoleListView : userRoleList){
            userRoleNames.add(userRoleListView.getRoleName());
        }

        /**
         * 获取角色菜单关系集合
         */
        List<RoleMenuListView> roleMenuList = mapper.getSysRoleMenuList(userIdModel.getId());
        for (RoleMenuListView roleMenuListView : roleMenuList){
            allPermissions.add(roleMenuListView.getMenuCode());
        }


        RoleNamesAndPermissionsView roleNamesAndPermissionsView = new RoleNamesAndPermissionsView();
        roleNamesAndPermissionsView.setUserRoleNames(userRoleNames);
        roleNamesAndPermissionsView.setAllPermissions(allPermissions);

        BaseResult<RoleNamesAndPermissionsView> baseResult = new BaseResult<>();
        baseResult.setModel(roleNamesAndPermissionsView);
        baseResult.setSuccess(true);
        return baseResult;
    }

    /**
     * 更新系统用户在线总时长
     * @param sysUserOnlineTimeModel
     * @return BaseResult<Boolean>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult<Boolean> updateSysUserTotalOnlineTime(SysUserOnlineTimeModel sysUserOnlineTimeModel) {
        boolean success = mapper.updateIgnoreNull(sysUserOnlineTimeModel.modelToEntity())==1;

        BaseResult<Boolean> result=new BaseResult<>();
        result.setModel(success);
        result.setSuccess(success);
        return result;
    }

    /**
     * 冻结系统用户
     * @param sysUserFreezeModel
     * @return BaseResult<Boolean>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult<Boolean> updateSysUserToFreeze(SysUserFreezeModel sysUserFreezeModel) {
        boolean success = mapper.updateIgnoreNull(sysUserFreezeModel.modelToEntity())==1;

        BaseResult<Boolean> result=new BaseResult<>();
        result.setModel(success);
        result.setSuccess(success);
        return result;
    }

    @Override
    public BaseResult<Integer> editLoginPwd(PwdEditModel pwdEditModel) {
        BaseResult<Integer> baseResult = new BaseResult<>();
        baseResult.setSuccess(true);

        SysUser sysUser = mapper.getById(pwdEditModel.getId());
        String s = AuthTool.md5SysUserPassword(pwdEditModel.getPassword(), sysUser.getLoginName());
        if(!sysUser.getLoginPwd().equals(s)){
            baseResult.setSuccess(false);
            baseResult.setMessage("旧密码不正确");
            return baseResult;
        }

        String newPwd = AuthTool.md5SysUserPassword(pwdEditModel.getNewPassword(), sysUser.getLoginName());
        sysUser.setLoginPwd(newPwd);
        int i = mapper.updateIgnoreNull(sysUser);
        baseResult.setModel(i);
        return baseResult;
    }
}
